package com.zxx.otherchaos.widgets.rickTip;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;

import com.zxx.otherchaos.R;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

/**
 * @author zxx on 2021/1/4
 */
public class RickyRecycleView extends RecyclerView {

    private View mScrollBarPanel;       //气泡布局
    private int mWidthMeasureSpec;
    private int mHeightMeasureSpec;
    private OnPositionChangedListener mPositionChangedListener;
    //定义滑动条的y坐标位置---》onScroll里面不断判断和赋值
    public int mScrollBarPanelPosition = 0;
    public Animation mInAnimation = null;
    public Animation mOutAnimation = null;

    //定义指示器在ListView中的y轴高度
    public int thumbOffset = 0;
    private int mLastPosition = -1; //index下标
    private int firstItemPosition;
    private LinearLayoutManager linearManager;

    public RickyRecycleView(@NonNull Context context) {
        this(context, null);
    }

    public RickyRecycleView(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RickyRecycleView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        addOnScrollListener(scrollListener);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        //初始化一些数据，比如动画
        final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ExtendedListView);
        int layoutId = a.getResourceId(R.styleable.ExtendedListView_scrollBarPanel, -1);
        int inAnimation = a.getResourceId(R.styleable.ExtendedListView_scrollBarPanelInAnimation, -1);
        int outAnimation = a.getResourceId(R.styleable.ExtendedListView_scrollBarPanelOutAnimation, -1);

        a.recycle();
        //设置气泡布局
        setScrollBarPanel(layoutId);
//        setVerticalScrollBarEnabled(true);
//        awakenScrollBars(200,true);

        mInAnimation = AnimationUtils.loadAnimation(context, inAnimation);
        mOutAnimation = AnimationUtils.loadAnimation(context, outAnimation);
        long durationMills = ViewConfiguration.getScrollBarFadeDuration();
        mOutAnimation.setDuration(durationMills);
        mOutAnimation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                //动画结束时，指示器隐藏
                if (mScrollBarPanel != null) {
                    mScrollBarPanel.setVisibility(GONE);
                }
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
    }

    //设置气泡布局
    private void setScrollBarPanel(int layoutId) {
        LinearLayoutManager manager = new LinearLayoutManager(getContext());
        this.setLayoutManager(manager);
        //1.渲染
        mScrollBarPanel = LayoutInflater.from(getContext()).inflate(layoutId, this, false);
        mScrollBarPanel.setVisibility(GONE);
        //通知所有View区调整大小以及绘制
        requestLayout();
    }

    //2.测量
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //这是测量ListView的控件
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //测量完后，测量当前自己的控件
        //测量气泡控件
        if (mScrollBarPanel != null && getAdapter() != null) {
            // 这个measure要考虑很多东西如padding，margin等计算
            //mScrollBarPanel.measure(width, height);

            mWidthMeasureSpec = widthMeasureSpec;
            mHeightMeasureSpec = heightMeasureSpec;

            //所以用以下测量,参一要测量的控件，参二父容器给的空间
            Log.e("Tag-->", "onMeasure:" + mScrollBarPanelPosition);
            measureChild(mScrollBarPanel, widthMeasureSpec, heightMeasureSpec);
        }
    }

    //3.摆放
    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        //摆放自己的气泡控件
        if (mScrollBarPanel != null && getAdapter() != null) {
            int left = getMeasuredWidth() - mScrollBarPanel.getMeasuredWidth() - getVerticalScrollbarWidth();
            int right = left + mScrollBarPanel.getMeasuredWidth();
            int bottom = mScrollBarPanelPosition + mScrollBarPanel.getMeasuredHeight();

            Log.e("Tag-->", "onLayout:" + mScrollBarPanelPosition);
            mScrollBarPanel.layout(left, mScrollBarPanelPosition, right, bottom);
        }
    }

    //4.显示
    @Override
    public void onDraw(Canvas c) {
        super.onDraw(c);
    }

    //4.绘制分发(用此方法显示)
    @Override
    protected void dispatchDraw(Canvas canvas) {
        super.dispatchDraw(canvas);
        //在ViewGroup绘制的时候，在上面追加一个自己绘制的气泡布局在上面
        if (mScrollBarPanel != null && mScrollBarPanel.getVisibility() == VISIBLE) {
            drawChild(canvas, mScrollBarPanel, getDrawingTime());
        }
    }

    private OnScrollListener scrollListener = new OnScrollListener() {

        @Override
        public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
            //Log.e("Tag-->", "onScrollStateChanged:" + firstItemPosition);


            LayoutManager layoutManager = recyclerView.getLayoutManager();

            //判断是当前layoutManager是否为LinearLayoutManager
            // 只有LinearLayoutManager才有查找第一个和最后一个可见view位置的方法
            if (layoutManager instanceof LinearLayoutManager) {
                linearManager = (LinearLayoutManager) layoutManager;
                //获取最后一个可见view的位置
                int lastItemPosition = linearManager.findLastVisibleItemPosition();
            }
        }

        @Override
        public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            //1.监听当前系统滑块在哪个位置，设置自己的滑块（气泡）的位置
            if (mScrollBarPanel != null) {
                //mScrollBarPanelPosition不断的控制这个值变化
                //computeVerticalScrollExtent();  //滑动条在纵向滑动范围内 它经过放大后自身的高度
                //computeVerticalScrollOffset();  //滑动条在纵向幅度的位置，屏幕中间5000
                //computeVerticalScrollRange();   //滑动的范围：0~10000

                //1.滑块的高度，思路：滑块的高度/ListView的高度 = extent/range
                int height = Math.round(1.0f * getMeasuredHeight() * computeVerticalScrollExtent() / computeVerticalScrollRange());

                //2.得到滑块中间的y 坐标，思路：滑块的高度/extent = y/offset
                thumbOffset = height * computeVerticalScrollOffset() / computeVerticalScrollExtent();
                thumbOffset += height / 2;

                if (mLastPosition == -1) {
                    //初始偏移量有点高，需要微调
                    mScrollBarPanelPosition = mScrollBarPanel.getHeight()/2;
                } else {
                    mScrollBarPanelPosition = thumbOffset - mScrollBarPanel.getHeight() / 2;
                }

                int left = getMeasuredWidth() - mScrollBarPanel.getMeasuredWidth() - getVerticalScrollbarWidth();
                int right = left + mScrollBarPanel.getMeasuredWidth();
                int bottom = mScrollBarPanelPosition + mScrollBarPanel.getHeight();

                //Log.e("Tag-->", "onScrolled:" + mScrollBarPanelPosition + " - " + thumbOffset + " - " + mScrollBarPanel.getHeight());
                mScrollBarPanel.layout(left, mScrollBarPanelPosition, right, bottom);

                //获取第一个可见view的位置
                if (linearManager != null)
                    firstItemPosition = linearManager.findFirstVisibleItemPosition();

                for (int i = 0; i < getChildCount(); i++) {
                    View childView = getChildAt(i);
                    if (childView != null) {
                        //是否在这个条目的top和bottom的范围内
                        //if (thumbOffset + height / 2 > childView.getTop() && thumbOffset + height / 2 < childView.getBottom()) {
                        if (thumbOffset + height / 3 > childView.getTop() && thumbOffset + height / 2 < childView.getBottom()) {
                            //下标到底在那个条目
                            if (mLastPosition != firstItemPosition + i) {
                                //当前条目=firstVisibleItem（第一个可见的item）+i
                                mLastPosition = firstItemPosition + i;

                                if (mPositionChangedListener != null)
                                    mPositionChangedListener.onPositionChanged(RickyRecycleView.this, mLastPosition, mScrollBarPanel);

                                //宽度会发生改变，需要重新测量一下
                                measureChild(mScrollBarPanel, mWidthMeasureSpec, mHeightMeasureSpec);
                            }
                        }
                    }
                }

            }
        }
    };


    //需要添加属性scrollbars=""，此方法才会走
    @Override
    protected boolean awakenScrollBars(int startDelay, boolean invalidate) {
        //唤醒滑块
        //判断系统的滑块是否唤醒--true:显示自己的气泡
        boolean awaken = super.awakenScrollBars(startDelay, invalidate);
//        boolean awaken = isVerticalScrollBarEnabled();
        //Log.e("Tag-->", "awakenScrollBars:" + awaken);
        if (awaken && mScrollBarPanel != null) {
            if (mScrollBarPanel.getVisibility() == GONE) {
                //动画进来
                mScrollBarPanel.setVisibility(VISIBLE);
                if (mInAnimation != null) {
                    mScrollBarPanel.startAnimation(mInAnimation);
                }
            }

            //不移除的话 会有很多runnable
            mHandler.removeCallbacks(runnable);

            //Log.e("Tag-->", "awakenScrollBars:" + startDelay + AnimationUtils.currentAnimationTimeMillis());
            //过半秒钟消失,系统滑块消失的时间+当前动画时长
            mHandler.postAtTime(runnable, startDelay + AnimationUtils.currentAnimationTimeMillis());
        }
        //
        return awaken;
    }

    private Handler mHandler = new Handler(Looper.getMainLooper());

    private final Runnable runnable = new Runnable() {
        @Override
        public void run() {
            if (mOutAnimation != null) {
                mScrollBarPanel.startAnimation(mOutAnimation);
            }
        }
    };


    public interface OnPositionChangedListener {
        void onPositionChanged(RickyRecycleView listView, int position, View scrollView);
    }

    public void setOnPositionChangedListener(OnPositionChangedListener listener) {
        this.mPositionChangedListener = listener;
    }

}
